from django.shortcuts import render,HttpResponse
from web.form.file import FolderModelForm, FileModelForm
from django.http import JsonResponse
from web import models
from utils.tencent.cos import deletefile, deletefile_list, credential
from django.views.decorators.csrf import csrf_exempt
import json
from utils.tencent.cos import check_file


#  http://127.0.0.1:8000/manage/1/file
#  http://127.0.0.1:8000/manage/1/file/?floder=3
def file(request, project_id):
    parent_object = None
    folder_id = request.GET.get('folder', "")
    if folder_id.isdecimal():
        parent_object = models.FileRepository.objects.filter(id=int(folder_id), file_type=2,
                                                             project=request.tracer.project).first()
    """文件列表  添加文件夹"""
    # 查看页面

    if request.method == "GET":
        breadcrumb_list = []
        parent = parent_object
        while parent:
            # 还有个更好的方法
            breadcrumb_list.insert(0, {'id': parent.id, 'name': parent.name})
            parent = parent.parent

        queryset = models.FileRepository.objects.filter(project=request.tracer.project)
        # 当前目录下所有文件夹以及文件
        if parent_object:
            file_object_list = queryset.filter(parent=parent_object).order_by('-file_type')
            # 进入某个目录
        else:
            # 根目录
            file_object_list = queryset.filter(parent__isnull=True).order_by('-file_type')
        form = FolderModelForm(request, parent_object)
        context = {'form': form,
                   'file_object_list': file_object_list,
                   'breadcrumb_list': breadcrumb_list,
                   'folder_object': parent_object}
        return render(request, 'web/file.html', context)
    # 添加文件夹 文件夹修改
    fid = request.POST.get('fid', '')
    edit_object = None
    if fid.isdecimal():
        # 修改
        edit_object = models.FileRepository.objects.filter(id=int(fid), file_type=2,
                                                           project=request.tracer.project).first()
    if edit_object:
        form = FolderModelForm(request, parent_object, data=request.POST, instance=edit_object)
    else:
        # 添加
        form = FolderModelForm(request, parent_object, data=request.POST)

    if form.is_valid():
        form.instance.project = request.tracer.project
        form.instance.file_type = 2
        form.instance.update_user = request.tracer.user
        form.instance.parent = parent_object
        form.save()
        return JsonResponse({'status': True})
    return JsonResponse({'status': False, 'error': form.errors})


#  http://127.0.0.1:8000/manage/1/file/delete/?fid=3
def file_delete(request, project_id):
    """删除文件"""
    fid = request.GET.get('fid')
    # 删除
    delete_object = models.FileRepository.objects.filter(id=fid, project=request.tracer.project).first()
    if delete_object.file_type == 1:
        """删除文件 （数据库删除，cos文件删除，项目的空间容量还回去） """
        # 它的默认单位是字节
        # 删除文件是将容量还给当前项目的已使用空间
        request.tracer.project.use_space -= delete_object.file_size
        request.tracer.project.save()

        # cos中删除文件
        deletefile(request.tracer.project.bucket, request.tracer.project.region,
                   delete_object.key)
        # 数据库中删除当前啊文件
        delete_object.delete()

        return JsonResponse({'status': True})

    else:
        """删除文件夹 （找到文件夹下所有的文件数据库删除，cos文件删除，项目的空间容量还回去）"""
        # models.FileRepository.objects.filter(parent=delete_object)
        totoal_size = 0
        key_list = []
        folder_list = [delete_object, ]

        for folder in folder_list:
            child_list = models.FileRepository.objects.filter(project=request.tracer.project,
                                                              parent=folder).order_by('-file_type')
            for child in child_list:
                # 文件夹
                if child.file_type == 2:
                    folder_list.append(child)
                else:
                    # 文件大小汇总
                    totoal_size += child.file_size
                    # 文件
                    key_list.append({"Key": child.key})
        # cos批量删除
        if key_list:
            deletefile_list(request.tracer.project.bucket, request.tracer.project.region,
                            key_list)
        if totoal_size:
            # 删除文件是将容量还给当前项目的已使用空间
            request.tracer.project.use_space -= totoal_size
            request.tracer.project.save()

        delete_object.delete()
        return JsonResponse({'status': True})


@csrf_exempt
def cos_credentials(request, project_id):
    """获取cos临时凭证"""
    # 做容量限制：  单文件&总文件
    # 获取要上传文件以及大小
    # 文件字节大小 item['size'] b
    # 拿到单文件限制的大小  M
    per_file_limit = request.tracer.price_policy.per_file_size * 1024 * 1024  # M ->kb ->b
    # 拿总文件限制
    total_file_limit = request.tracer.price_policy.project_space * 1024 * 1024 * 1024  # G
    file_list = json.loads(request.body.decode('utf-8'))

    total_size = 0
    for item in file_list:
        if item['size'] > per_file_limit:
            msg = '单文件超出限制(最大{}M),文件:{}'.format(request.tracer.price_policy.per_file_size, item['name'])
            return JsonResponse({'status': False, 'error': msg})
    total_size += item['size']
    # 总容量限制
    # request.tracer.price_policy.project_space #项目允许的空间
    # request.tracer.project.use_space  #项目已使用
    if request.tracer.project.use_space + total_size > total_file_limit:
        return JsonResponse({'status': False, 'error': '容量超出限制，请升级套餐'})

    data_dict = credential(request.tracer.project.bucket, request.tracer.project.region)
    return JsonResponse({'status': True, 'data': data_dict})


@csrf_exempt
def file_post(request, project_id):
    """将已上传成功文件写入数据库"""
    # 更具key再去cos获取文件Etag ，etag相当于腾讯云返回值中的一个id
    # name: fileSize,
    # key: key,
    # file_size: fileSize,
    # parent: CURRENRFOLDER,
    # etag: data.ETag,
    # file_path: data.Location
    # print(request.POST)
    # key = request.POST.get('key')
    # result = check_file(request.tracer.project.bucket, request.tracer.project.region, key)
    # print(result)
    form = FileModelForm(request, data=request.POST)
    if form.is_valid():
        # 校验通过  写入数据库

        # 通过ModelForm.save()存储到数据库中的数据返回instance对象，无法通过get_xx_display_获取到choice对的中文
        # form.instance.file_type = 1
        # form.instance.update_user = request.tracer.user
        # instance =  form.save()
        data_list = form.cleaned_data
        # print(data_list)
        data_list.pop('etag')
        data_list.update({'project': request.tracer.project, 'file_type': 1, 'update_user': request.tracer.user})
        instance = models.FileRepository.objects.create(**data_list)
        # 当前项目的已使用空间：更新   file_size是字节
        request.tracer.project.use_space += data_list['file_size']
        request.tracer.project.save()
        result = {
            'id': instance.id,
            'name': instance.name,
            # 'file_type': instance.get_file_type_display(),
            'file_size': instance.file_size,
            'username': instance.update_user.username,
            'datatime': instance.update_datetime,

        }
        return JsonResponse({'status': True, 'data': result})

    return JsonResponse({{'status': False, 'data': "文件错误"}})

    # models.FileRepository.objects.create()


def file_download(request, project_id,file_id):
    """下载文件"""
    # 文件内容
    # 响应头
    # 打开文件，获取文件的内容 去cos获取文件内容
    import requests
    file_object = models.FileRepository.objects.filter(id=file_id, project_id=project_id).first()
    res = requests.get(file_object.file_path)

    # 文件分块处理（适用于大文件）     @孙歆尧
    data = res.iter_content()

    # 设置content_type=application/octet-stream 用于提示下载框        @孙歆尧
    response = HttpResponse(data, content_type="application/octet-stream")
    from django.utils.encoding import escape_uri_path

    # 设置响应头：中文件文件名转义      @王洋
    response['Content-Disposition'] = "attachment; filename={};".format(escape_uri_path(file_object.name))
    return response
